package com.android.server.mock.performer;

import android.annotation.NonNull;
import android.content.ContentResolver;
import android.content.Context;
import android.os.mock.MockManager;
import android.provider.Settings;
import com.android.server.mock.performer.settings.MockSettingsItem;
import com.android.server.mock.performer.settings.MockSettingsItemHolder;
import android.util.Log;

import java.util.List;

public class MockSettingsPerformer extends MockPerformer<MockSettingsPerformer> {
    private static final String TAG = "MockSettingsPerformer";

    private MockSettingsItemHolder holder;

    @Override
    public void initMock() {
        String jsonStr = getPsInfo(MockManager.KEY_INPUT_DEVICE);
        holder = MockSettingsItemHolder.create(jsonStr);
    }

    @Override
    public void reset() {
        holder = null;
    }

    public void startMock(@NonNull Context context) {
        if (holder == null) {
            Log.e(TAG, "start: holder is null");
            return;
        }
        setData(context.getContentResolver(), holder);
    }

    private void setData(ContentResolver r, MockSettingsItemHolder holder) {
        setGlobal(r, holder.getGlobalList());
        setSystem(r, holder.getSystemList());
        setSecure(r, holder.getSecureList());
    }

    private static void setGlobal(ContentResolver r, List<MockSettingsItem> list) {
        for (MockSettingsItem item : list) {
            Class<?> type = identifyType(item.getValue());
            if (type == int.class) {
                Settings.Global.putInt(r, item.getName(), Integer.parseInt(item.getValue()));
            } else if (type == long.class) {
                Settings.Global.putLong(r, item.getName(), Long.parseLong(item.getValue()));
            } else if (type == float.class) {
                Settings.Global.putFloat(r, item.getName(), Float.parseFloat(item.getValue()));
            } else {
                Settings.Global.putString(r, item.getName(), item.getValue());
            }
        }
    }

    private static void setSystem(ContentResolver r, List<MockSettingsItem> list) {
        for (MockSettingsItem item : list) {
            Class<?> type = identifyType(item.getValue());
            if (type == int.class) {
                Settings.System.putInt(r, item.getName(), Integer.parseInt(item.getValue()));
            } else if (type == long.class) {
                Settings.System.putLong(r, item.getName(), Long.parseLong(item.getValue()));
            } else if (type == float.class) {
                Settings.System.putFloat(r, item.getName(), Float.parseFloat(item.getValue()));
            } else {
                Settings.System.putString(r, item.getName(), item.getValue());
            }
        }
    }

    private static void setSecure(ContentResolver r, List<MockSettingsItem> list) {
        for (MockSettingsItem item : list) {
            Class<?> type = identifyType(item.getValue());
            if (type == int.class) {
                Settings.Secure.putInt(r, item.getName(), Integer.parseInt(item.getValue()));
            } else if (type == long.class) {
                Settings.Secure.putLong(r, item.getName(), Long.parseLong(item.getValue()));
            } else if (type == float.class) {
                Settings.Secure.putFloat(r, item.getName(), Float.parseFloat(item.getValue()));
            } else {
                Settings.Secure.putString(r, item.getName(), item.getValue());
            }
        }
    }

    @NonNull
    public static Class<?> identifyType(String str) {
        if (str == null || str.isEmpty()) {
            return String.class;
        }

        try {
            Integer.parseInt(str);
            return int.class;
        } catch (NumberFormatException e) {
            try {
                Long.parseLong(str);
                return long.class;
            } catch (NumberFormatException e1) {
                try {
                    Float.parseFloat(str);
                    return float.class;
                } catch (NumberFormatException e2) {
                    return String.class;
                }
            }
        }
    }
}
